#ifndef _WORLDSERVER_H_
#define _WORLDSERVER_H_

#define DISP_OK		DISPMSG( " [OK]\n" );
#define DISP_FAIL	DISPMSG( " Failed!\n" );

#include <windows.h>
#include "Singleton.h"
#include <map>
#include "const.h"
#include "Timer.h"
#include "ServerStruct.h"
#include "DataBaseEngine.h"


using namespace std;

class IOCPServer;
class Session;
class ServerSession;
class NetworkObject;


class PatchServer : public Singleton<PatchServer>
{
	enum {	CLIENT_IOHANDLER = 0,
			SERVER_IOHANDLER = 1 };

	friend NetworkObject* CallBackOnAccept( DWORD dwNetworkIndex );
	friend VOID CallBackOnDisconnect( DWORD dwSessionIndex, NetworkObject *pNetworkObject );

public:
	PatchServer();
	~PatchServer();

	VOID					UpdateServerTitle();
	BOOL					Init();
	VOID					Release();
	VOID					Run();
	BOOL					Update();
	VOID					StartListen();
	VOID					StartListen( char *szIP, WORD wPort, char *szInnerIP, WORD wInnerPort );
	VOID					ConnectToServer( NetworkObject *pNetworkObject, char *pszIP, WORD wPort );
	inline VOID				Shutdown() { m_bShutdown = TRUE; }
	inline BOOL				IsOnShutdown() { return m_bShutdown; }
	inline VOID				SetServerKey( SERVER_KEY key ) { m_ServerKey = key; }
	inline SERVER_KEY		GetServerKey() { return m_ServerKey; }
	inline DWORD			GetWorldID() { return m_ServerKey.GetWorldID(); }
	inline DWORD			GetChannelID() { return m_ServerKey.GetChannelID(); }
	inline DWORD			GetServerID() { return m_ServerKey.GetServerID(); }
	VOID					ConnectToDBProxyServer();
	BOOL					ProcessConsole();
	VOID					ReadAndSendNotice();
	BOOL					IsConnectedTo( eSERVER_TYPE eServerType );

	VOID					SetGameDBProxyServerAddr( TCHAR* tszDBProxyIP, WORD wDBProxyPort );
	VOID					ConnectToGameDBProxyServer();

	inline eSERVER_TYPE		GetServerType() { return WORLD_SERVER; }
private:
	VOID					UpdateFPS();
	VOID					DisplayServerInfo();
	VOID					MaintainConnection();
	IOCPServer				*m_pIOCPServer;
	BOOL					m_bShutdown;
	DWORD					m_dwFPS;
	Timer				m_ReconnectTimer;
	SERVER_KEY				m_ServerKey;
};

extern CDataBaseEngine   g_DataBaseIns;

#endif // _WORLDSERVER_H_